package top.eggcode.base;

import org.hibernate.Session;

import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import java.util.Optional;

/**
 * Title: 实体类管理器 for 磁盘
 * Description: 不建议在业务中使用
 * Date: 2021/3/29 9:26
 *
 * @author JiaQi Ding
 * @version 1.0
 */
public class SimpleStoreImp<T> implements SimpleStore<T> {
    private final Class<T> clazz;

    @PersistenceContext
    protected javax.persistence.EntityManager manager;

    @SuppressWarnings("unchecked")
    public SimpleStoreImp() {
        ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
        this.clazz = ((Class<T>) type.getActualTypeArguments()[0]);
    }

    protected Session getSession() {
        return manager.unwrap(Session.class);
    }

    @Override
    public Optional<T> get(String id) {
        return Optional.of(manager.find(clazz, id));
    }

    @Override
    public List<T> selectAll() {
        String text = "from " +
                clazz.getName();
        return manager.createQuery(text, clazz).getResultList();
    }

    @Override
    public void add(T entity) {
        manager.persist(entity);
    }

    @Override
    public void batchAdd(List<T> entityList) {
        entityList.forEach(entity -> manager.persist(entity));
    }

    /**
     * 更新数据
     * 只针对未被JPA容器管理的实体
     *
     * @param entity 实体
     */
    @Override
    public void update(T entity) {
        manager.merge(entity);
        manager.flush();
    }

    @Override
    public void batchUpdate(List<T> entityList) {
        entityList.forEach(entity -> manager.merge(entity));
        manager.flush();
    }

    @Override
    public void delete(T entity) {
        manager.remove(entity);
    }

    /**
     * 移除对象
     * 针对持久化对象
     *
     * @param entityList 实体集合
     */
    @Override
    public void batchDelete(List<T> entityList) {
        entityList.forEach(entity -> manager.remove(entity));
    }

    @Override
    public List<T> nativeQuery(String ql, Class<T> entity) {
        return manager.createQuery(ql, entity).getResultList();
    }

    @Override
    public int nativeUpdate(String ql, List<Object> parameterList) {
        Query query = manager.createQuery(ql);
        int i = 1;
        for (Object parameter : parameterList) {
            query.setParameter(i, parameter);
            ++i;
        }
        return query.executeUpdate();
    }

    @Override
    public int nativeDelete(String ql, List<Object> parameterList) {
        Query query = manager.createQuery(ql);
        int i = 1;
        for (Object parameter : parameterList) {
            query.setParameter(i, parameter);
            ++i;
        }
        return query.executeUpdate();
    }

}
